package com.openapi.protocol.decode;

import com.openapi.data.JT808PackageData;
import com.openapi.data.JT808PushData;
import com.openapi.protocol.decode.subPackageHandle.handle.GpsHandle;
import com.openapi.protocol.decode.subPackageHandle.mediaData.MediaDataParse_0801;
import com.openapi.protocol.decode.subPackageHandle.terminalPositionInfoUpload.TerminalPositionInfoUpload_0x0704;
import exsun.jt808.data.parseUtil.GpsUtil;
import exsun.jt808.data.upload_data.GpsData;
import exsun.jt808.data.upload_data.GpsStatusType;
import exsun.jt808.data.upload_data.Jt808EntityBase;
import exsun.jt808.data.upload_data.jt808.*;
import exsun.jt808.data.util.parse.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;

/**
 * 808数据解析
 */
@Component
public class Analyze808 {

	private final static Logger logger = LoggerFactory.getLogger(Analyze808.class);

//	@Autowired
//	private  MediaDataParse_0801 mediaDataParse_0801;
//
//	@Autowired
//	private TerminalPositionInfoUpload_0x0704 terminalPositionInfoUpload_0x0704;

	public Jt808EntityBase gpsDecoder(JT808PackageData packageData){
		return GpsHandle.decode(packageData);
	}

//	public  List<JT808PushData> mediaDecoder(JT808PackageData packageData){
//		return mediaDataParse_0801.decode(packageData);
//	}
//
//	public  JT808PushData terminalPositionInfoUploadDecoder(JT808PackageData packageData){
//		return terminalPositionInfoUpload_0x0704.decode(packageData);
//	}

	/**
	 * 终端通用应答
	 * @param packageData
	 * @return
	 */
	public  Jt808EntityBase terminalCommonResponseDecoder(JT808PackageData packageData)
	{
		byte[] body = packageData.getBodyBuffers();
		if(body.length == 0)return null;
		TerminalCommonResponse response = new TerminalCommonResponse();
		response.setOrgSerialNum(DecoderUtils.parseIntFromBytes(body, 0, 2));
		response.setOrgMsgId(DecoderUtils.parseIntFromBytes(body, 2, 2));
		response.setResult(DecoderUtils.parseIntFromBytes(body, 4, 1));
		return response;
	}

	/**
	 * 终端心跳
	 * @param packageData
	 * @return
	 */
	public  Jt808EntityBase terminalHearBeatDecoder(JT808PackageData packageData) {
		// 消息体为空
		return new TerminalHearBeat();
	}

	/**
	 * 终端登录鉴权
	 * @param packageData
	 * @return
	 */
	public  Jt808EntityBase terminalAuthenticationDecoder(JT808PackageData packageData)
	{
		byte[] body = packageData.getBodyBuffers();
		TerminalAuthentication data = new TerminalAuthentication();
		data.setAuthorizeCode(DecoderUtils.parseStringFromBytes(body, 0, body.length));
		return data;
	}

	/**
	 * 终端注册
	 * @param packageData
	 * @return
	 */
	public  Jt808EntityBase terminalRegisterDecoder(JT808PackageData packageData)
	{
		byte[] body = packageData.getBodyBuffers();
		TerminalRegister data = new TerminalRegister();
		data.setProvincialId(DecoderUtils.parseIntFromBytes(body, 0, 2));
		data.setCityId(DecoderUtils.parseIntFromBytes(body, 2, 2));
		data.setManufacturerId(DecoderUtils.parseStringFromBytes(body, 4, 5));
		data.setTerminalType(DecoderUtils.parseStringFromBytes(body, 9, 20));
		data.setTerminalId(DecoderUtils.parseStringFromBytes(body, 29, 7));
		data.setLicensePlateColor(DecoderUtils.parseIntFromBytes(body, 36, 1));
		data.setVehicleLicensePlate(DecoderUtils.parseStringFromBytes(body, 37, body.length - 37));
		return data;
	}

	/**
	 * 终端退登
	 * @param packageData
	 * @return
	 */
	public  Jt808EntityBase terminalLogoutDecoder(JT808PackageData packageData) {
		// 终端注销消息体为空
		return new TerminalLogout();
	}

	/**
	 * 行驶记录数据上传
	 * @param packageData
	 * @return
	 */
	public  Jt808EntityBase collectDataDecoder(JT808PackageData packageData)
	{
		byte[] body = packageData.getBodyBuffers();
		CollectDataResponse data = new CollectDataResponse();
		data.setReqSerialNo(DecoderUtils.parseIntFromBytes(body, 0, 2));
		data.setCmd(DecoderUtils.parseIntFromBytes(body, 2, 1));
		data.setData(DecoderUtils.parseBcdStringFromBytes(body, 3, body.length - 3));
		return data;
	}
	/*
	驾驶员身份信息采集上报
	 */
	public  Jt808EntityBase driverInfoUploadDecoder(JT808PackageData packageData)
	{
		byte[] body = packageData.getBodyBuffers();
		DriverInfo data = new DriverInfo();
		data.setStatus(DecoderUtils.parseIntFromBytes(body, 0, 1));
		data.setTime(DecoderUtils.parseBcdStringFromBytes(body, 1, 6));
		if (data.getStatus() == 1)
		{
			//System.out.println("heh");
			data.setIcCardreadResult(DecoderUtils.parseIntFromBytes(body, 7, 1));
			if (data.getIcCardreadResult() == 0)
			{
				int n = body[8];
				data.setDriverName(DecoderUtils.parseStringFromBytes(body, 9, n));
				data.setQualificationCode(DecoderUtils.parseStringFromBytes(body, 9 + n, 20));
				int m = body[29 + n];
				data.setIssuingAuthority(DecoderUtils.parseStringFromBytes(body, 30 + n, m));
				data.setCertificateValidity(DecoderUtils.parseBcdStringFromBytes(body, 30 + n + m, 4));
			}
		}
		// 存mongodb（驾驶员、车辆对应关系）
//        driverVehicleStatMongoService.insert(data, clientId);
//        statDriverIdDetailService.save(data, clientId);
		return data;
	}

	/**
	 * 总线数据上传
	 * @param packageData
	 * @return
	 */
	public  Jt808EntityBase CANDataDecoder(JT808PackageData packageData)
	{
		byte[] body = packageData.getBodyBuffers();
		CanData data = new CanData();
		List<CanDataItem> items = new ArrayList<CanDataItem>();
		int count = DecoderUtils.parseIntFromBytes(body, 0, 2);
		data.setTime(DecoderUtils.parseStringFromBytes(body, 2, 5));
		int index = 8;
		for (int n = 0; n < count; n++)
		{
			CanDataItem item = new CanDataItem();
			int canId = DecoderUtils.parseIntFromBytes(body, index, 5);
			item.setCanChannelId((canId & 0x80000000) >> 31);
			item.setFrameType((canId & 0x40000000) >> 30);
			item.setCollectType((canId & 0x20000000) >> 29);
			item.setCanId((canId & 0x1fffffff));
			index += 4;
			item.setCanData(DecoderUtils.parseStringFromBytes(body, index, 8));
			index += 8;
			items.add(item);
		}
		data.setItems(items);
		return data;
	}

	/**
	 * 电子运单上报
	 * @param packageData
	 * @return
	 */
	public  Jt808EntityBase electronicWaybillDecoder(JT808PackageData packageData)
	{
		byte[] body = packageData.getBodyBuffers();
		ElectronicWaybill data = new ElectronicWaybill();
		int len = DecoderUtils.parseIntFromBytes(body, 0, 4);
		data.setWaybill(DecoderUtils.parseStringFromBytes(body, 4, len));
		// 添加到mongodb
//        vehicleEwayBillMongoService.insertEwayBill(waybill, clientId);
		return data;
	}

	/**
	 * 事件报告
	 * @param packageData
	 * @return
	 */
	public  Jt808EntityBase eventUploadDecoder(JT808PackageData packageData)
	{
		byte[] body = packageData.getBodyBuffers();
		EventUpload data = new EventUpload();
		data.setEventId(DecoderUtils.parseIntFromBytes(body, 0, 1));
		return data;
	}

	/**
	 * 多媒体事件信息上传
	 * @param packageData
	 * @return
	 */
	public  Jt808EntityBase mediaEventDecoder(JT808PackageData packageData)
	{
		byte[] body = packageData.getBodyBuffers();
		MediaEvent data = new MediaEvent();
		data.setMediaId(DecoderUtils.parseIntFromBytes(body, 0, 4));
		data.setMediaType(DecoderUtils.parseIntFromBytes(body, 4, 1));
		data.setCodingType(DecoderUtils.parseIntFromBytes(body, 5, 1));
		data.setEventType(DecoderUtils.parseIntFromBytes(body, 6, 1));
		data.setChannelId(DecoderUtils.parseIntFromBytes(body, 7, 1));
		return data;
	}

	/**
	 * 存储多媒体数据检索应答
	 * @param packageData
	 * @return
	 */
	public  Jt808EntityBase mediaDataDecoder(JT808PackageData packageData)
	{
		byte[] body = packageData.getBodyBuffers();
		MediaQueryResponseList data = new MediaQueryResponseList();
		ArrayList<MediaQueryResponse> mediaQueryResponses = new ArrayList<MediaQueryResponse>();
		int count = DecoderUtils.parseIntFromBytes(body, 2, 3);
		int Index = 4;
		for (int n = 0; n < count; n++)
		{
			MediaQueryResponse item = new MediaQueryResponse();
			item.setMediaId(DecoderUtils.parseIntFromBytes(body, Index, 4));
			Index += 4;
			item.setMediaType(DecoderUtils.parseIntFromBytes(body, Index, 1));
			Index += 1;
			item.setChannelId(DecoderUtils.parseIntFromBytes(body, Index, 1));
			Index += 1;
			item.setEventType(DecoderUtils.parseIntFromBytes(body, Index, 1));
			Index += 1;
			String strPosition = HexStrUtil.encodeHex(DecoderUtils.byteCopy(body, Index, 28));
//            item.setPositionInfo(jt808ParseUtil.getPositionInfo(clientId, "true", strPosition));
			Index += 28;
			mediaQueryResponses.add(item);
			data.setMediaQueryResponseList(mediaQueryResponses);
		}
		return data;
	}

	/**
	 * 摄像头立即拍摄指令应答
	 * @param packageData
	 * @return
	 */
	public  Jt808EntityBase takePhotoRightAwayDecoder(JT808PackageData packageData)
	{
		byte[] body = packageData.getBodyBuffers();
		TakePhotoRightAwayResponse data = new TakePhotoRightAwayResponse();
		data.setRepSerialNo(DecoderUtils.parseIntFromBytes(body, 0, 2));
		data.setResult(DecoderUtils.parseIntFromBytes(body, 2, 1));
		int count = DecoderUtils.parseIntFromBytes(body, 3, 2);
		List<Integer> mediaIds = new ArrayList<Integer>();
		int index = 5;
		for (int n = 0; n < count; n++)
		{
			mediaIds.add(DecoderUtils.parseIntFromBytes(body, index, 4));
			data.setMediaIds(mediaIds);
			index += 4;
		}
		return data;
	}

	//位置信息查询应答
	public Jt808EntityBase QueryPositionInfoDecoder(JT808PackageData packageData){
		byte[] body = packageData.getBodyBuffers();
		GpsData data = new GpsData();
		data.setSerialNo(DecoderUtils.parseIntFromBytes(body,0,2));
		data.setAlm(GpsUtil.GetAlarm(HexStrUtil.byteArrToBinStr(body, 2, 4)));
		data.setAmm(BitOperator.fourBytesToLong(body, 2));
		data.setSts(GpsUtil.GetStatus(HexStrUtil.byteArrToBinStr(body, 6, 4)));
		data.addSts(GpsStatusType.getBlindSpot());
		data.setStm(BitOperator.fourBytesToLong(body, 6));
		data.setLat(Integer.parseInt(HexStrUtil.encodeHex(body, 10, 4), 16) / 1000000.0);
		data.setLng(Integer.parseInt(HexStrUtil.encodeHex(body, 14, 4), 16) / 1000000.0);
		data.setHgt(HexStrUtil.bytesToInt(body, 18, 2));
		data.setSpd(HexStrUtil.bytesToInt(body, 20, 2) / 10);
		data.setDre(HexStrUtil.bytesToInt(body, 22, 2));
		data.setGte(TimeUtil.parseTime(HexStrUtil.encodeHex(body, 24, 6), TimeUtil.dateFormatyyMMddHHmmss));
		data.setGdt(TimeUtil.getDateByFormat(data.getGte(), TimeUtil.dateFormatYMDHMS));
		if (TimeUtil.getOffectDay(TimeUtil.getNowTimeStamp(), data.getGte()) > 7)
		{
			data.setGte(TimeUtil.getNowTimeStamp());
			data.setGdt(TimeUtil.getDateByFormat(data.getGte(), TimeUtil.dateFormatYMDHMS));
		}
		GpsUtil.ParseGpsExtenstionInfo(body, data);
		return data;
	}

	/**
	 * 查询终端参数应答
	 * @param packageData
	 * @return
	 */
	public  Jt808EntityBase terminalQueryParamResponseDecoder(JT808PackageData packageData)
	{
		byte[] body = packageData.getBodyBuffers();
		TerminalParameters data = new TerminalParameters();
		data.setSerialNo(DecoderUtils.parseIntFromBytes(body, 0, 2));
		int parasCount = DecoderUtils.parseIntFromBytes(body, 2, 1);
		int index = 3;
		for (int n = 0; n < parasCount; n++)
		{
			int paraId = DecoderUtils.parseIntFromBytes(body, index, 4);
			index += 4;
			int paraLen = DecoderUtils.parseIntFromBytes(body, index, 1);
			index += 1;
			if(index >= body.length)break;
			switch (paraId) {
				case 0x0001:
				{
					data.setHeartbeatInterval(DecoderUtils.parseIntFromBytes(body, index, paraLen));
					index += paraLen;
					break;
				}
				case 0x0002:
				{
					data.setTcpResponseTimeout(DecoderUtils.parseIntFromBytes(body, index, paraLen));
					index += paraLen;
					break;
				}
				case 0x0003:
				{
					data.setTcpRetransmissionCount(DecoderUtils.parseIntFromBytes(body, index, paraLen));
					index += paraLen;
					break;
				}
				case 0x0004:
				{
					data.setUdpResponseTimeout(DecoderUtils.parseIntFromBytes(body, index, paraLen));
					index += paraLen;
					break;
				}
				case 0x0005:
				{
					data.setUdpRetransmissionCount(DecoderUtils.parseIntFromBytes(body, index, paraLen));
					index += paraLen;
					break;
				}
				case 0x0006:
				{
					data.setSmsResponseTimeout(DecoderUtils.parseIntFromBytes(body, index, paraLen));
					index += paraLen;
					break;
				}
				case 0x0007:
				{
					data.setSmsRetransmissionCount(DecoderUtils.parseIntFromBytes(body, index, paraLen));
					index += paraLen;
					break;
				}
				case 0x0010:
				{
					data.setMainServerApn(DecoderUtils.parseStringFromBytes(body, index, paraLen));
					index += paraLen;
					break;
				}
				case 0x0011:
				{
					data.setMainServerUsername(DecoderUtils.parseStringFromBytes(body, index, paraLen));
					index += paraLen;
					break;
				}
				case 0x0012:
				{
					data.setMainServerPassword(DecoderUtils.parseStringFromBytes(body, index, paraLen));
					index += paraLen;
					break;
				}
				case 0x0013:
				{
					data.setMainServerAddress(DecoderUtils.parseStringFromBytes(body, index, paraLen));
					index += paraLen;
					break;
				}
				case 0x0014:
				{
					data.setBackupServerApn(DecoderUtils.parseStringFromBytes(body, index, paraLen));
					index += paraLen;
					break;
				}
				case 0x0015:
				{
					data.setBackupServerUsername(DecoderUtils.parseStringFromBytes(body, index, paraLen));
					index += paraLen;
					break;
				}
				case 0x0016:
				{
					data.setBackupServerPassword(DecoderUtils.parseStringFromBytes(body, index, paraLen));
					index += paraLen;
					break;
				}
				case 0x0017:
				{
					data.setBackupServerAddress(DecoderUtils.parseStringFromBytes(body, index, paraLen));
					index += paraLen;
					break;
				}
				case 0x0018:
				{
					data.setServerTcpPort(DecoderUtils.parseIntFromBytes(body, index, paraLen));
					index += paraLen;
					break;
				}
				case 0x0019:
				{
					data.setServerUdpPort(DecoderUtils.parseIntFromBytes(body, index, paraLen));
					index += paraLen;
					break;
				}
				case 0x001A:
				{
					data.setRoadTransportIcCardServerAddress(DecoderUtils.parseStringFromBytes(body, index, paraLen));
					index += paraLen;
					break;
				}
				case 0x001B:
				{
					data.setRoadTransportIcCardServerTcpPort(DecoderUtils.parseIntFromBytes(body, index, paraLen));
					index += paraLen;
					break;
				}
				case 0x001C:
				{
					data.setRoadTransportIcCardServerUdpPort(DecoderUtils.parseIntFromBytes(body, index, paraLen));
					index += paraLen;
					break;
				}
				case 0x001D:
				{
					data.setRoadTransportIcCardBackupServerAddress(DecoderUtils.parseStringFromBytes(body, index, paraLen));
					index += paraLen;
					break;
				}
				case 0x0020:
				{
					data.setReportingLocationPolicy(DecoderUtils.parseIntFromBytes(body, index, paraLen));
					index += paraLen;
					break;
				}
				case 0x0021:
				{
					data.setReportingLocationProgramme(DecoderUtils.parseIntFromBytes(body, index, paraLen));
					index += paraLen;
					break;
				}
				case 0x0022:
				{
					data.setDriversNotLoggedInDistanceReportingInterval(DecoderUtils.parseIntFromBytes(body, index, paraLen));
					index += paraLen;
					break;
				}
				case 0x0027:
				{
					data.setDormantReportingInterval(DecoderUtils.parseIntFromBytes(body, index, paraLen));
					index += paraLen;
					break;
				}
				case 0x0028:
				{
					data.setEmergencyAlarmReportingInterval(DecoderUtils.parseIntFromBytes(body, index, paraLen));
					index += paraLen;
					break;
				}
				case 0x0029:
				{
					data.setDefaultReportingInterval(DecoderUtils.parseIntFromBytes(body, index, paraLen));
					index += paraLen;
					break;
				}
				case 0x002C:
				{
					data.setDefaultDistanceReportingInterval(DecoderUtils.parseIntFromBytes(body, index, paraLen));
					index += paraLen;
					break;
				}
				case 0x002D:
				{
					data.setDriversNotLoggedInDistanceReportingInterval(DecoderUtils.parseIntFromBytes(body, index, paraLen));
					index += paraLen;
					break;
				}
				case 0x002E:
				{
					data.setDormantDistanceReportingInterval(DecoderUtils.parseIntFromBytes(body, index, paraLen));
					index += paraLen;
					break;
				}
				case 0x002F:
				{
					data.setEmergencyAlarmDistanceReportingInterval(DecoderUtils.parseIntFromBytes(body, index, paraLen));
					index += paraLen;
					break;
				}
				case 0x0030:
				{
					data.setInflectionPoint(DecoderUtils.parseIntFromBytes(body, index, paraLen));
					index += paraLen;
					break;
				}
				case 0x0031:
				{
					data.setElectronicFenceRadius(DecoderUtils.parseIntFromBytes(body, index, paraLen));
					index += paraLen;
					break;
				}
				case 0x0040:
				{
					data.setMonitoringPlatformPhoneNum(DecoderUtils.parseStringFromBytes(body, index, paraLen));
					index += paraLen;
					break;
				}
				case 0x0041:
				{
					data.setResetPhoneNum(DecoderUtils.parseStringFromBytes(body, index, paraLen));
					index += paraLen;
					break;
				}
				case 0x0042:
				{
					data.setRestoreFactoryPhoneNum(DecoderUtils.parseStringFromBytes(body, index, paraLen));
					index += paraLen;
					break;
				}
				case 0x0043:
				{
					data.setMonitoringPlatformSmsPhoneNum(DecoderUtils.parseStringFromBytes(body, index, paraLen));
					index += paraLen;
					break;
				}
				case 0x0044:
				{
					data.setReceiveDeviceSmsAlarmPhoneNum(DecoderUtils.parseStringFromBytes(body, index, paraLen));
					index += paraLen;
					break;
				}
				case 0x0045:
				{
					data.setTelephoneAnsweringStrategy(DecoderUtils.parseIntFromBytes(body, index, paraLen));
					index += paraLen;
					break;
				}
				case 0x0046:
				{
					data.setEveryTimeTheLongestTalkTime(DecoderUtils.parseIntFromBytes(body, index, paraLen));
					index += paraLen;
					break;
				}
				case 0x0047:
				{
					data.setCurrentMonthTheLongestTalkTime(DecoderUtils.parseIntFromBytes(body, index, paraLen));
					index += paraLen;
					break;
				}
				case 0x0048:
				{
					data.setMonitorPhoneNum(DecoderUtils.parseStringFromBytes(body, index, paraLen));
					index += paraLen;
					break;
				}
				case 0x0049:
				{
					data.setMonitoringPlatformPrivilegesSmsPhoneNum(DecoderUtils.parseStringFromBytes(body, index, paraLen));
					index += paraLen;
					break;
				}
				case 0x0050:
				{
					data.setAlarmScreenCharacter(DecoderUtils.parseIntFromBytes(body, index, paraLen));
					index += paraLen;
					break;
				}
				case 0x0051:
				{
					data.setAlarmSendSmsSwitch(DecoderUtils.parseIntFromBytes(body, index, paraLen));
					index += paraLen;
					break;
				}
				case 0x0052:
				{
					data.setAlarmTakePicSwitch(DecoderUtils.parseIntFromBytes(body, index, paraLen));
					index += paraLen;
					break;
				}
				case 0x0053:
				{
					data.setAlarmTakePicSaveSwitch(DecoderUtils.parseIntFromBytes(body, index, paraLen));
					index += paraLen;
					break;
				}
				case 0x0054:
				{
					data.setKeySwitch(DecoderUtils.parseIntFromBytes(body, index, paraLen));
					index += paraLen;
					break;
				}
				case 0x0055:
				{
					data.setTheHighestSpeed(DecoderUtils.parseIntFromBytes(body, index, paraLen));
					index += paraLen;
					break;
				}
				case 0x0056:
				{
					data.setSpeedingDuration(DecoderUtils.parseIntFromBytes(body, index, paraLen));
					index += paraLen;
					break;
				}
				case 0x0057:
				{
					data.setContinuousDrivingTimeThreshold(DecoderUtils.parseIntFromBytes(body, index, paraLen));
					index += paraLen;
					break;
				}
				case 0x0058:
				{
					data.setCumulativeDrivingTimeThresholdInTheDay(DecoderUtils.parseIntFromBytes(body, index, paraLen));
					index += paraLen;
					break;
				}
				case 0x0059:
				{
					data.setTheMinimumRestTime(DecoderUtils.parseIntFromBytes(body, index, paraLen));
					index += paraLen;
					break;
				}
				case 0x005A:
				{
					data.setTheMaximumParkingTime(DecoderUtils.parseIntFromBytes(body, index, paraLen));
					index += paraLen;
					break;
				}
				case 0x005B:
				{
					data.setOverspeedAlarmVaule((float) (DecoderUtils.parseIntFromBytes(body, index, paraLen) / 10.0));
					index += paraLen;
					break;
				}
				case 0x005C:
				{
					data.setTiredDriveringVaule(DecoderUtils.parseIntFromBytes(body, index, paraLen));
					index += paraLen;
					break;
				}
				case 0x005D:
				{
					int temp = DecoderUtils.parseIntFromBytes(body, index, paraLen);
					data.setCollisionAlarmTime((temp & 0xff) * 4);
					data.setCollisionAcceleration((temp & 0xff00) >> 8);
					index += paraLen;
					break;
				}
				case 0x005E:
				{
					data.setCartwheelAlarmAngle(DecoderUtils.parseIntFromBytes(body, index, paraLen));
					index += paraLen;
					break;
				}
				case 0x0064:
				{
					int temp = DecoderUtils.parseIntFromBytes(body, index, paraLen);
					data.setChannel1TimingTakePhotoFlag(temp & 0x01);
					data.setChannel2TimingTakePhotoFlag((temp & 0x02) >> 1);
					data.setChannel3TimingTakePhotoFlag((temp & 0x04) >> 2);
					data.setChannel4TimingTakePhotoFlag((temp & 0x08) >> 3);
					data.setChannel5TimingTakePhotoFlag((temp & 0x10) >> 4);
					data.setChannel1TimingTakePhotoStorageFlag((temp & 0x0100) >> 8);
					data.setChannel2TimingTakePhotoStorageFlag((temp & 0x0200) >> 9);
					data.setChannel3TimingTakePhotoStorageFlag((temp & 0x0400) >> 10);
					data.setChannel4TimingTakePhotoStorageFlag((temp & 0x0800) >> 11);
					data.setChannel5TimingTakePhotoStorageFlag((temp & 0x1000) >> 12);
					data.setTimingUnit((temp & 0x010000) >> 16);
					data.setTimingInterval((temp & 0xfffe0000) >> 17);
					index += paraLen;
					break;
				}
				case 0x0065:
				{
					int temp = DecoderUtils.parseIntFromBytes(body, index, paraLen);
					data.setChannel1IntervalTakePhotoFlag(temp & 0x01);
					data.setChannel2IntervalTakePhotoFlag((temp & 0x02) >> 1);
					data.setChannel3IntervalTakePhotoFlag((temp & 0x04) >> 2);
					data.setChannel4IntervalTakePhotoFlag((temp & 0x08) >> 3);
					data.setChannel5IntervalTakePhotoFlag((temp & 0x10) >> 4);
					data.setChannel1IntervalTakePhotoStorageFlag((temp & 0x0100) >> 8);
					data.setChannel2IntervalTakePhotoStorageFlag((temp & 0x0200) >> 9);
					data.setChannel3IntervalTakePhotoStorageFlag((temp & 0x0400) >> 10);
					data.setChannel4IntervalTakePhotoStorageFlag((temp & 0x0800) >> 11);
					data.setChannel5IntervalTakePhotoStorageFlag((temp & 0x1000) >> 12);
					data.setIntervalUnit((temp & 0x010000) >> 16);
					data.setSpacingInterval((temp & 0xfffe0000) >> 17);
					index += paraLen;
					break;
				}
				case 0x0070:
				{
					data.setImageVideoQuality(DecoderUtils.parseIntFromBytes(body, index, paraLen));
					index += paraLen;
					break;
				}
				case 0x0071:
				{
					data.setBrightness(DecoderUtils.parseIntFromBytes(body, index, paraLen));
					index += paraLen;
					break;
				}
				case 0x0072:
				{
					data.setContrast(DecoderUtils.parseIntFromBytes(body, index, paraLen));
					index += paraLen;
					break;
				}
				case 0x0073:
				{
					data.setSaturation(DecoderUtils.parseIntFromBytes(body, index, paraLen));
					index += paraLen;
					break;
				}
				case 0x0074:
				{
					data.setChroma(DecoderUtils.parseIntFromBytes(body, index, paraLen));
					index += paraLen;
					break;
				}
				case 0x0075:{
					data.setActivationCode(DecoderUtils.parseStringFromBytes(body, index, paraLen));
					index += paraLen;
					break;
				}
				case 0x0080:
				{
					data.setVehicleOdometerReadings((float) (DecoderUtils.parseIntFromBytes(body, index, paraLen) / 10.0));
					index += paraLen;
					break;
				}
				case 0x0081:
				{
					data.setProvincialId(DecoderUtils.parseIntFromBytes(body, index, paraLen));
					index += paraLen;
					break;
				}
				case 0x0082:
				{
					data.setCityId(DecoderUtils.parseIntFromBytes(body, index, paraLen));
					index += paraLen;
					break;
				}
				case 0x0083:
				{
					data.setTheLicensePlateNumber(DecoderUtils.parseStringFromBytes(body, index, paraLen));
					index += paraLen;
					break;
				}
				case 0x0084:
				{
					data.setLicensePlateColor(DecoderUtils.parseIntFromBytes(body, index, paraLen));
					index += paraLen;
					break;
				}
				case 0x0090:
				{
					int temp = DecoderUtils.parseIntFromBytes(body, index, paraLen);
					data.setGpsPositioningFlag(temp & 0x01);
					data.setBdPositioningFlag((temp & 0x02) >> 1);
					data.setGlonassPositioningFlag((temp & 0x04) >> 2);
					data.setGalileoPositioningFlag((temp & 0x08) >> 3);
					index += paraLen;
					break;
				}
				case 0x0091:
				{
					data.setGnssBaudRate(DecoderUtils.parseIntFromBytes(body, index, paraLen));
					index += paraLen;
					break;
				}
				case 0x0092:
				{
					data.setGnssLocationingOutputFrequency(DecoderUtils.parseIntFromBytes(body, index, paraLen));
					index += paraLen;
					break;
				}
				case 0x0093:
				{
					data.setGnssLocationingCollectFrequency(DecoderUtils.parseIntFromBytes(body, index, paraLen));
					index += paraLen;
					break;
				}
				case 0x0094:
				{
					data.setGnssLocationingUploadType(DecoderUtils.parseIntFromBytes(body, index, paraLen));
					index += paraLen;
					break;
				}
				case 0x0095:
				{
					data.setGnssLocationingUploadUnit(DecoderUtils.parseIntFromBytes(body, index, paraLen));
					index += paraLen;
					break;
				}
				case 0x0100:
				{
					data.setCan1CollectTimeInterval(DecoderUtils.parseIntFromBytes(body, index, paraLen));
					index += paraLen;
					break;
				}
				case 0x0101:
				{
					data.setCan1UploadTimeInterval(DecoderUtils.parseIntFromBytes(body, index, paraLen));
					index += paraLen;
					break;
				}
				case 0x0102:
				{
					data.setCan2CollectTimeInterval(DecoderUtils.parseIntFromBytes(body, index, paraLen));
					index += paraLen;
					break;
				}
				case 0x0103:
				{
					data.setCan2UploadTimeInterval(DecoderUtils.parseIntFromBytes(body, index, paraLen));
					index += paraLen;
					break;
				}
				case 0x0110:
				{
					int tempH = DecoderUtils.parseIntFromBytes(body, index, paraLen / 2);
					int tempL = DecoderUtils.parseIntFromBytes(body, index + 4, paraLen / 2);
					data.setCollectTimeInterval(tempH & 0xffffffff);
					data.setCanChannelId((tempL & 0x80000000) >> 31);
					data.setFramesType((tempL & 0x40000000) >> 30);
					data.setDataCollectType((tempL & 0x20000000) >> 29);
					data.setCanId(tempL & 0x1fffffff);
					index += paraLen;
					break;
				}
				case 0x00FC:
				{
					data.setCalibrationValue(DecoderUtils.parseStringFromBytes(body,index,paraLen));
					index += paraLen;
					break;
				}
				case 0x00FD:
				{
					data.setCompensationValue(DecoderUtils.parseStringFromBytes(body,index,paraLen));
					index += paraLen;
					break;
				}
				case 0x00FE:
				{
					data.setArmLength(DecoderUtils.parseStringFromBytes(body,index,paraLen));
					index += paraLen;
					break;
				}
				case 0x00FF:
				{
					data.setIdentificationCard(DecoderUtils.parseStringFromBytes(body,index,paraLen));
					index += paraLen;
					break;
				}
				default:
					index += paraLen;
					break;
			}
		}
		return data;
	}

	/**
	 * 查询终端属性应答
	 * @param packageData
	 * @return
	 */
	public Jt808EntityBase terminalQueryPropResponseDecoder(JT808PackageData packageData)
	{
		byte[] body = packageData.getBodyBuffers();
		TerminalProperty data = new TerminalProperty();
		int type = DecoderUtils.parseIntFromBytes(body, 0, 2);
		data.setApplyPassengerVehicle(type & 0x01);
		data.setApplyDangerousVehicle((type & 0x02) >> 1);
		data.setApplyGeneralCargoVehicle((type & 0x04) >> 2);
		data.setApplyRentedOutVehicle((type & 0x08) >> 3);
		data.setHardDiskRecord((type & 0x40) >> 6);
		data.setModel((type & 0x80) >> 7);
		data.setTerminalManufacturerCode(DecoderUtils.parseStringFromBytes(body, 2, 5));
		data.setTerminalModel(DecoderUtils.parseStringFromBytes(body, 7, 20));
		data.setTerminalId(DecoderUtils.parseStringFromBytes(body, 27, 7));
		data.setICCID(DecoderUtils.parseBcdStringFromBytes(body, 34, 10));
		int n = body[44];
		data.setTerminalHardwareVersion(DecoderUtils.parseBcdStringFromBytes(body, 45, n));
		int m = body[45 + n];
		data.setTerminalFirmwareVersion(DecoderUtils.parseBcdStringFromBytes(body, 46 + n, m));
		int gnssProp = body[46 + n + m];
		data.setGpsLocationing(gnssProp & 0x01);
		data.setBdLocationing((gnssProp & 0x02) >> 1);
		data.setGlonassLocationing((gnssProp & 0x04) >> 2);
		data.setGalileoLocationing((gnssProp & 0x08) >> 3);
		int communicationProp = DecoderUtils.parseIntFromBytes(body, 47 + n + m, 1);
		data.setGprs(communicationProp & 0x01);
		data.setCdma((communicationProp & 0x02) >> 1);
		data.setTdScdma((communicationProp & 0x04) >> 2);
		data.setWcdma((communicationProp & 0x08) >> 3);
		data.setCdma2000((communicationProp & 0x10) >> 4);
		data.setTdLte((communicationProp & 0x20) >> 5);
		data.setOtherComunication((communicationProp & 0x80) >> 7);
		return data;
	}

	/**
	 * 终端升级结果通知
	 * @param packageData
	 * @return
	 */
	public  Jt808EntityBase upgradeResponseDecoder(JT808PackageData packageData)
	{
		byte[] body = packageData.getBodyBuffers();
		UpgradeResponse data = new UpgradeResponse();
		data.setType(DecoderUtils.parseIntFromBytes(body, 0, 1));
		data.setResult(DecoderUtils.parseIntFromBytes(body, 1, 1));
		return data;
	}

	/**
	 * 车辆控制应答
	 * @param packageData
	 * @return
	 */
	public Jt808EntityBase vehicleControlResponseDecoder(JT808PackageData packageData) {
//        String strPosition = msgBody.substring(4, msgBody.length());
//        PositionInfo data = jt808ParseUtil.getPositionInfo(clientId, "true", strPosition);
		TerminalLogout data = new TerminalLogout();
		return data;
	}

	/**
	 * 农机自动标定应答
	 */
	public Jt808EntityBase AutoCalibrationResponse(JT808PackageData packageData){
		byte[] body = packageData.getBodyBuffers();
		AutoCalibrationResponse data = new AutoCalibrationResponse();
		data.setFlag(DecoderUtils.parseIntFromBytes(body,0,1));
		return data;
	}


	//数据上行透传
	public  Jt808EntityBase uplinkPassThroughDecoder(JT808PackageData packageData){
		byte[] body = packageData.getBodyBuffers();
		UplinkPassthrough data = new UplinkPassthrough();

		int itemId = DecoderUtils.parseIntFromBytes(body,0,1);
		data.setMsgType(itemId);
		switch (itemId){
			case 0x00:
				data.setContent(DecoderUtils.parseStringFromBytes(body,1,body.length-1));
				break;
			case 0x41:
				byte[] Bytes = new byte[7];
				System.arraycopy(body, 1, Bytes, 0, 7);
				int crc = CRC16.GetCRC16(Bytes);
//				int crc = CRC16.getCRC(Bytes);
				if (DecoderUtils.parseIntFromBytes(body,8,2) == crc){
					data.setAddressCode(DecoderUtils.parseIntFromBytes(body,1,1));
					data.setFunctionCode(DecoderUtils.parseIntFromBytes(body,2,1));
					data.setCodeNum(DecoderUtils.parseIntFromBytes(body,3,1));
					data.setPmTwoPointFive(DecoderUtils.parseIntFromBytes(body,4,2));
					data.setPmTen(DecoderUtils.parseIntFromBytes(body,6,2));
					data.setLow(DecoderUtils.parseIntFromBytes(body,8,1));
					data.setHigh(DecoderUtils.parseIntFromBytes(body,9,1));
				}
				break;
		}

		return data;

	}

}
